

package sketch.ui;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import sketch.doc.Sketch;
import sketch.doc.SketchContainer;
import sketch.ink.SampledPoint;
import sketch.ink.Stroke;
import sketch.ink.StrokeContainer;
import sketch.parse.Parser;
import sketch.seg.cd.CDFactory;
import sketch.semantics.SemanticGraph;
import sketch.semantics.link.LinkSGG;
import sketch.shape.Shape;
import sketch.shape.geom.prim.Point;

/**
 *
 * @author  zhengwt
 */
public class SketchFrame extends javax.swing.JFrame {

    private JMenu jMenuEdit;
	private JMenuItem jMenuEditDelete;
	private JMenuItem jMenuEditMoveTo;


	public SketchFrame() {
        initComponents();
    }

//    public javax.swing.JLabel getJLabelH1() {
//    	if (jLabelH1 == null) {
//    		jLabelH1 = new JLabel();
//    		jLabelH1.setText("H1");
//    	}
//		return jLabelH1;
//	}
//
//	public javax.swing.JLabel getJLabelK1() {
//		if (jLabelK1 == null) {
//			jLabelK1 = new JLabel();
//			jLabelK1.setText("K1");
//		}
//		return jLabelK1;
//	}
//
//	public javax.swing.JLabel getJLabelH2() {
//    	if (jLabelH2 == null) {
//    		jLabelH2 = new JLabel();
//    		jLabelH2.setText("H2");
//    	}
//		return jLabelH2;
//	}
//
//	public javax.swing.JLabel getJLabelK2() {
//		if (jLabelK2 == null) {
//			jLabelK2 = new JLabel();
//			jLabelK2.setText("K2");
//		}
//		return jLabelK2;
//	}
//
//	public javax.swing.JLabel getJLabelRho() {
//		if (jLabelRho == null) {
//			jLabelRho = new JLabel();
//			jLabelRho.setText("Number of corners");
//		}
//		return jLabelRho;
//	}

	public javax.swing.JPanel getJPanelCxt() {
		if (jPanelCxt == null) {
			jPanelCxt = new JPanel();

			org.jdesktop.layout.GroupLayout jPanelCxtLayout = new org.jdesktop.layout.GroupLayout(jPanelCxt);
	        jPanelCxt.setLayout(jPanelCxtLayout);
	        jPanelCxtLayout.setHorizontalGroup(
	            jPanelCxtLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(jPanelCxtLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJButtonParse())
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJCheckBoxAutoParse())
	                .addContainerGap(31, Short.MAX_VALUE))
	            .add(getJScrollPaneCxt(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
	            .add(jPanelCxtLayout.createSequentialGroup()
	                .add(getJScrollPaneCxtTable(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)
	                .addContainerGap())
	            .add(jPanelCxtLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJLabelDomain())
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJComboBoxDomain(), 0, 143, Short.MAX_VALUE)
	                .addContainerGap())
	            .add(jPanelCxtLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJButtonParse2())
	                .addContainerGap(94, Short.MAX_VALUE))
	        );
	        jPanelCxtLayout.setVerticalGroup(
	            jPanelCxtLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(jPanelCxtLayout.createSequentialGroup()
	                .add(getJScrollPaneCxt(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 383, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJScrollPaneCxtTable(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 89, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(jPanelCxtLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
	                    .add(getJLabelDomain())
	                    .add(getJComboBoxDomain(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
	                .add(8, 8, 8)
	                .add(jPanelCxtLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
	                    .add(getJButtonParse())
	                    .add(getJCheckBoxAutoParse()))
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJButtonParse2())
	                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
	        );
		}
		return jPanelCxt;
	}

	public javax.swing.JPanel getJPanelInk() {
		if (jPanelInk == null) {
			jPanelInk = new JPanel();

			org.jdesktop.layout.GroupLayout jPanelInkLayout = new org.jdesktop.layout.GroupLayout(jPanelInk);
	        jPanelInk.setLayout(jPanelInkLayout);
	        jPanelInkLayout.setHorizontalGroup(
	            jPanelInkLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(getJScrollPaneInk(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)
	            .add(jPanelInkLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJLabelCDMethod())
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJComboBoxCDMethod(), 0, 106, Short.MAX_VALUE)
	                .addContainerGap())
	            .add(jPanelInkLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJButtonSeg())
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJCheckBoxAutoSeg(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
	                .addContainerGap())
	            .add(jPanelInkLayout.createSequentialGroup()
	                .addContainerGap()
	                .add(getJButtonPA())
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(getJCheckBoxAutoPA(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)
	                .addContainerGap())
	        );

	        jPanelInkLayout.linkSize(new java.awt.Component[] {getJButtonPA(), getJButtonSeg()}, org.jdesktop.layout.GroupLayout.HORIZONTAL);

	        jPanelInkLayout.setVerticalGroup(
	            jPanelInkLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(jPanelInkLayout.createSequentialGroup()
	                .add(getJScrollPaneInk(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 450, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
	                .add(14, 14, 14)
	                .add(jPanelInkLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
	                    .add(getJLabelCDMethod())
	                    .add(getJComboBoxCDMethod(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
	                .add(jPanelInkLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
	                    .add(getJButtonSeg())
	                    .add(getJCheckBoxAutoSeg()))
	                .add(4, 4, 4)
	                .add(jPanelInkLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
	                    .add(getJButtonPA())
	                    .add(getJCheckBoxAutoPA()))
	                .addContainerGap())
	        );
		}
		return jPanelInk;
	}

	public javax.swing.JScrollPane getJScrollPaneCxtTable() {
		if (jScrollPaneCxtTable == null) {
			jScrollPaneCxtTable = new JScrollPane();
			jScrollPaneCxtTable.setViewportView(getJTableCxt());
		}
		return jScrollPaneCxtTable;
	}

	public javax.swing.JTable getJTableCxt() {
		if (jTableCxt == null) {
			jTableCxt = new JTable();
//			jTableCxt.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
			jTableCxt.setEnabled(false);

			if (SketchContainer.get().getSelectedShapes().size() == 1) {
				Shape shape = SketchContainer.get().getSelectedShapes().get(0);

				if (shape != null) {
					jTableCxt.setModel(new DefaultTableModel(
							shape.getFieldValues(),
							new String[] {"Field", "Value"}
					));
				}
			}
		}
		return jTableCxt;
	}

//	public javax.swing.JTextField getJTextFieldH1() {
//		if (jTextFieldH1 == null) {
//			jTextFieldH1 = new JTextField();
//			jTextFieldH1.setEditable(false);
//		}
//		return jTextFieldH1;
//	}
//
//	public javax.swing.JTextField getJTextFieldK1() {
//		if (jTextFieldK1 == null) {
//			jTextFieldK1 = new JTextField();
//			jTextFieldK1.setEditable(false);
//		}
//		return jTextFieldK1;
//	}
//
//	public javax.swing.JTextField getJTextFieldH2() {
//		if (jTextFieldH2 == null) {
//			jTextFieldH2 = new JTextField();
//			jTextFieldH2.setEditable(false);
//		}
//		return jTextFieldH2;
//	}
//
//	public javax.swing.JTextField getJTextFieldK2() {
//		if (jTextFieldK2 == null) {
//			jTextFieldK2 = new JTextField();
//			jTextFieldK2.setEditable(false);
//		}
//		return jTextFieldK2;
//	}
//
//	public javax.swing.JTextField getJTextFieldRho() {
//		if (jTextFieldRho == null) {
//			jTextFieldRho = new JTextField();
//			jTextFieldRho.setEditable(false);
//		}
//		return jTextFieldRho;
//	}

	public javax.swing.JMenuBar getJMenuBar() {
    	if (jMenuBar == null) {
    		jMenuBar = new javax.swing.JMenuBar();

    		jMenuBar.add(getJMenuFile());
    		jMenuBar.add(getJMenuView());
    		jMenuBar.add(getJMenuEdit());
            jMenuBar.add(getJMenuAction());

    	}
		return jMenuBar;
	}

	public JMenu getJMenuEdit() {
		if (jMenuEdit == null) {
			jMenuEdit = new JMenu();
			jMenuEdit.setText("Edit");

			jMenuEdit.add(getJMenuEditDelete());
			jMenuEdit.add(getJMenuEditMoveTo());
		}
		return jMenuEdit;
	}

	public JMenuItem getJMenuEditDelete() {
		if (jMenuEditDelete == null) {
			jMenuEditDelete = new JMenuItem();
			jMenuEditDelete.setText("Delete");
			jMenuEditDelete.setAccelerator(KeyStroke.getKeyStroke("DELETE"));

			jMenuEditDelete.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					int tab = getJTabbedPane().getSelectedIndex();
					if (tab == 0) {
						SketchContainer.get().removeSelectedStrokes();
					} else {
						SketchContainer.get().removeSelectedShapes();
					}//TODO

					repaint();
				}}
			);
		}
		return jMenuEditDelete;
	}

	private Point curMousePos = new Point();

	public JMenuItem getJMenuEditMoveTo() {
		if (jMenuEditMoveTo == null) {
			jMenuEditMoveTo = new JMenuItem();
			jMenuEditMoveTo.setText("Move to ...");
			jMenuEditMoveTo.setAccelerator(KeyStroke.getKeyStroke('m'));

			jMenuEditMoveTo.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					int tab = getJTabbedPane().getSelectedIndex();
					if (tab == 0) {
//						System.out.println("Move to " + curMousePos);
						SketchContainer.get().moveSelectedStrokesTo(curMousePos);
					} else {
						//TODO
					}

					getJPanelSketch().repaint();
				}

			});
		}
		return jMenuEditMoveTo;
	}

	public javax.swing.JMenu getJMenuFile() {
		if (jMenuFile == null) {
			jMenuFile = new javax.swing.JMenu();
			jMenuFile.setText("File");

			jMenuFile.add(getJMenuFileNew());
			jMenuFile.addSeparator();

			jMenuFile.add(getJMenuFileSave());
			jMenuFile.add(getJMenuFileLoad());

			jMenuFile.addSeparator();
			jMenuFile.add(getJMenuOption());
			jMenuFile.addSeparator();

			jMenuFile.add(getJMenuFileExit());
		}
		return jMenuFile;
	}

	public JMenuItem getJMenuFileExit() {
		if (jMenuFileExit == null) {
			jMenuFileExit = new JMenuItem();
			jMenuFileExit.setText("Exit");
			jMenuFileExit.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					SketchFrame.this.dispose();
				}

			});
		}
		return jMenuFileExit;
	}

	public JMenuItem getJMenuFileNew() {
		if (jMenuFileNew == null) {
			jMenuFileNew = new JMenuItem();
			jMenuFileNew.setText("New");
			jMenuFileNew.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					SketchContainer.get().reset();
					repaint();
				}

			});
		}
		return jMenuFileNew;
	}

	public javax.swing.JPanel getJPanelSketch() {
		if (jPanelSketch == null) {
			jPanelSketch = new javax.swing.JPanel() {
				public void paint(Graphics arg0) {
					super.paint(arg0);
					Graphics2D g2 = (Graphics2D) arg0;

					if (getJMenuViewHybrid().isSelected()) {
						SketchContainer.get().drawShapes(g2);
						SketchContainer.get().drawInk(g2);
						SketchContainer.get().drawSelectedShape(g2);
						SketchContainer.get().drawSelectedStroke(g2);

						StrokeContainer.get().draw(g2);
						return;
					}

					if (getJMenuViewInk().isSelected()) {
						SketchContainer.get().drawRawInk(g2);
						SketchContainer.get().drawSelectedStroke(g2);

						StrokeContainer.get().draw(g2);
						return;
					}

					if (getJMenuViewCxt().isSelected()) {
						SketchContainer.get().drawShapes(g2);
						SketchContainer.get().drawSelectedShape(g2);
						return;
					}
				}
			};



			jPanelSketch.addMouseMotionListener(new MouseMotionListener() {

				public void mouseDragged(MouseEvent e) {
					StrokeContainer.get().appendPoint(new SampledPoint(e.getX(), e.getY()));
					StrokeContainer.get().draw((Graphics2D)getJPanelSketch().getGraphics());
				}

				public void mouseMoved(MouseEvent e) {
					curMousePos = new Point(e.getX(), e.getY());
				}

			});

			jPanelSketch.addMouseListener(new MouseAdapter() {

				@Override
				public void mousePressed(MouseEvent e) {
					super.mousePressed(e);
					StrokeContainer.get().appendPoint(new SampledPoint(e.getX(), e.getY()));
				}

				@Override
				public void mouseReleased(MouseEvent e) {
					super.mouseReleased(e);
					SketchContainer.get().addInk(StrokeContainer.fetch());
					StrokeContainer.reset();

					if (getJCheckBoxAutoSeg().isSelected()) {
						SketchContainer.get().segment();
					}
					if (getJCheckBoxAutoPA().isSelected()) {
						SketchContainer.get().primApproximate();
					}
					if (getJCheckBoxAutoParse().isSelected()) {
						SketchContainer.get().parse();
					}

					repaint();

				}

			});

			jPanelSketch.setBackground(new java.awt.Color(255, 255, 255));
	        org.jdesktop.layout.GroupLayout jPanelSketchLayout = new org.jdesktop.layout.GroupLayout(jPanelSketch);
	        jPanelSketch.setLayout(jPanelSketchLayout);
	        jPanelSketchLayout.setHorizontalGroup(
	            jPanelSketchLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(0, 749, Short.MAX_VALUE)
	        );
	        jPanelSketchLayout.setVerticalGroup(
	            jPanelSketchLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
	            .add(0, 548, Short.MAX_VALUE)
	        );
		}
		return jPanelSketch;
	}

	public javax.swing.JScrollPane getJScrollPaneInk() {
		if (jScrollPaneInk == null) {
			jScrollPaneInk = new javax.swing.JScrollPane();
			jScrollPaneInk.setViewportView(getJTreeInk());
		}
		return jScrollPaneInk;
	}

	public javax.swing.JScrollPane getJScrollPaneCxt() {
		if (jScrollPaneCxt == null) {
			jScrollPaneCxt = new JScrollPane();
			jScrollPaneCxt.setViewportView(getJTreeCxt());
		}
		return jScrollPaneCxt;
	}

	public javax.swing.JTabbedPane getJTabbedPane() {
		if (jTabbedPane == null) {
			jTabbedPane = new javax.swing.JTabbedPane();
			jTabbedPane.addTab("Ink", getJPanelInk());
	        jTabbedPane.addTab("Context", getJPanelCxt());

//	        jTabbedPane.addTab("Semantics", getJPanelSemantics());
//	        jTabbedPane.addChangeListener(new ChangeListener() {
//
//				public void stateChanged(ChangeEvent arg0) {
//					int sel = getJTabbedPane().getSelectedIndex();
//					if (sel == 0)
//						showInk();
//					else if (sel == 1)
//						showCxt();
//
//					getJPanelSketch().repaint();
//				}
//
//	        });
		}
		return jTabbedPane;
	}

	public javax.swing.JToolBar getJToolBar() {
		if (jToolBar == null) {
			jToolBar = new javax.swing.JToolBar();
			jToolBar.setFloatable(false);

//			jToolBar.add(getJButtonClearSelection());
//			jToolBar.add(getJButtonProcessAll());
		}
		return jToolBar;
	}

    private void initComponents() {

    	setTitle("Final Sketch Prototype");
//    	setSize(1000,800);
    	setLocation(10, 10);
    	setResizable(false);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        setJMenuBar(getJMenuBar());

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(getJToolBar(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1000, Short.MAX_VALUE)
            .add(layout.createSequentialGroup()
                .add(getJPanelSketch(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(getJTabbedPane(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(getJToolBar(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 25, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(getJPanelSketch(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(getJTabbedPane(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 640, Short.MAX_VALUE)))
        );
        pack();

        //TODO: init code
        getJCheckBoxAutoSeg().setSelected(false);
        getJCheckBoxAutoPA().setSelected(false);
        getJCheckBoxAutoParse().setSelected(false);
        getJTabbedPane().setSelectedIndex(0);
    }

    public static void main(String args[]) {

    	try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new SketchFrame().setVisible(true);
            }
        });
    }

//    private javax.swing.JLabel jLabelH1;
//    private javax.swing.JLabel jLabelK1;
//    private javax.swing.JLabel jLabelH2;
//    private javax.swing.JLabel jLabelK2;
//    private javax.swing.JLabel jLabelRho;

    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenu jMenuAction;
    private JMenu jMenuView;
//    private JMenu jMenuOption;
//
//    public JMenu getJMenuOption() {
//    	if (jMenuOption == null) {
//    		jMenuOption = new JMenu();
//    		jMenuOption.setText("Option");
//
//
//    	}
//    	return jMenuOption;
//    }

    public JMenu getJMenuView() {
    	if (jMenuView == null) {
    		jMenuView = new JMenu();
    		jMenuView.setText("View");

    		jMenuView.add(getJMenuViewHybrid());
    		jMenuView.add(getJMenuViewInk());
    		jMenuView.add(getJMenuViewCxt());

    	}
    	return jMenuView;
    }

    public JMenu getJMenuAction() {
    	if (jMenuAction == null) {
    		jMenuAction = new JMenu();
    		jMenuAction.setText("Action");

    		jMenuAction.add(getJMenuActionSegment());
    		jMenuAction.add(getJMenuActionPA());
    		jMenuAction.add(getJMenuActionParse());

    		//TODO
    		jMenuAction.add(getJMenuActionParse2());
    		jMenuAction.add(getJMenuActionSemantics());

    		jMenuAction.addSeparator();
    		jMenuAction.add(getJMenuActionOffLineParse());
    	}
    	return jMenuAction;
    }

    public JMenuItem getJMenuActionOffLineParse() {
    	if (jMenuActionOffLineParse == null) {
    		jMenuActionOffLineParse = new JMenuItem();
    		jMenuActionOffLineParse.setText("Off Line Parse");

    		jMenuActionOffLineParse.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					SketchContainer.get().off_line_parse();

					repaint();
				}
			});
    	}
    	return jMenuActionOffLineParse;
    }

    private JMenuItem jMenuActionOffLineParse;

    private javax.swing.JButton jButtonPA;
    private javax.swing.JButton jButtonSeg;
    private javax.swing.JCheckBox jCheckBoxAutoSeg;
    private javax.swing.JCheckBox jCheckBoxAutoPA;
    private javax.swing.JComboBox jComboBoxCDMethod;
    private javax.swing.JLabel jLabelCDMethod;
    private javax.swing.JLabel jLabelCorner;
    private javax.swing.JTextField jTextFieldCorner;

    private JButton jButtonParse;
    private JButton jButtonParse2;
    private JCheckBox jCheckBoxAutoParse;

    private javax.swing.JPanel jPanelCxt;
    private javax.swing.JPanel jPanelInk;
    private javax.swing.JPanel jPanelSketch;
    private javax.swing.JScrollPane jScrollPaneCxt;
    private javax.swing.JScrollPane jScrollPaneCxtTable;
    private javax.swing.JScrollPane jScrollPaneInk;
    private javax.swing.JTabbedPane jTabbedPane;
    private javax.swing.JTable jTableCxt;
//    private javax.swing.JTextField jTextFieldH1;
//    private javax.swing.JTextField jTextFieldK1;
//    private javax.swing.JTextField jTextFieldH2;
//    private javax.swing.JTextField jTextFieldK2;
//    private javax.swing.JTextField jTextFieldRho;
    private javax.swing.JToolBar jToolBar;

    private JTree jTreeInk;
    private JTree jTreeCxt;

    private JMenuItem jMenuFileNew;
    private JMenu jMenuFileSave;
    private JMenuItem jMenuFileLoad;
    private JMenuItem jMenuFileExit;

    private JMenuItem jMenuFileSaveInk;

    private JMenuItem jMenuActionSegment;
    private JMenuItem jMenuActionPA;
    private JMenuItem jMenuActionParse;
    private JMenuItem jMenuActionParse2;

    private JMenuItem jMenuActionSemantics;

    private JFileChooser jFileChooser;

    public JFileChooser getJFileChooser() {
    	if (jFileChooser == null) {
    		jFileChooser = new JFileChooser();
    		try {
				jFileChooser.setCurrentDirectory(new File(new File("./src/sketch/template").getCanonicalPath()));
			} catch (Exception e) {
				e.printStackTrace();
			}
    	}
    	return jFileChooser;
    }

    public JMenuItem getJMenuFileLoad() {
    	if (jMenuFileLoad == null) {
    		jMenuFileLoad = new JMenuItem();
    		jMenuFileLoad.setText("Load");

    		jMenuFileLoad.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					int result = getJFileChooser().showOpenDialog(SketchFrame.this);
					if (result == JFileChooser.APPROVE_OPTION) {
						File file = getJFileChooser().getSelectedFile();
						System.out.println("Load from file: " + file.getName());

						SketchContainer.get().readFromFile(file);
						SketchContainer.get().cornerDetect();
						repaint();
					}
				}

    		});
    	}
    	return jMenuFileLoad;
    }

    public JMenu getJMenuFileSave() {
    	if (jMenuFileSave == null) {
    		jMenuFileSave = new JMenu();
    		jMenuFileSave.setText("Save ...");

    		jMenuFileSave.add(getJMenuFileSaveInk());
    	}
    	return jMenuFileSave;
    }

    public JMenuItem getJMenuFileSaveInk() {
    	if (jMenuFileSaveInk == null) {
    		jMenuFileSaveInk = new JMenuItem();
    		jMenuFileSaveInk.setText("Ink");

    		jMenuFileSaveInk.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					int result = getJFileChooser().showSaveDialog(SketchFrame.this);
					if (result == JFileChooser.APPROVE_OPTION) {
						File file = getJFileChooser().getSelectedFile();
						System.out.println("Save ink to file: " + file.getName());

						SketchContainer.get().saveToFile(file, Sketch.INK);
					}
				}

    		});
    	}
    	return jMenuFileSaveInk;
    }

    //TODO
    public JMenuItem getJMenuActionSemantics() {
    	if (jMenuActionSemantics == null) {
    		jMenuActionSemantics = new JMenuItem();
    		jMenuActionSemantics.setText("Print semantics");
    		jMenuActionSemantics.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					SemanticGraph sg = SemanticGraph.generateSemanticGraph(SketchContainer.get().open(), new LinkSGG());
					System.out.println(sg.toString());
				}

    		});
    	}
    	return jMenuActionSemantics;
    }

    private JMenuItem jMenuViewInk;
    private JMenuItem jMenuViewCxt;
    private JMenuItem jMenuViewHybrid;

    private JMenuItem jMenuOption;

    public JMenuItem getJMenuOption() {
    	if (jMenuOption == null) {
    		jMenuOption = new JMenuItem();
    		jMenuOption.setText("Option");

    		jMenuOption.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
//					new SketchOption().setVisible(true);
				}

    		});
    	}
    	return jMenuOption;
    }

    private JButton jButtonProcessAll;
    private JButton jButtonClearSelection;

    public JButton getJButtonProcessAll() {
    	if (jButtonProcessAll == null) {
    		jButtonProcessAll = new JButton();
    		jButtonProcessAll.setText("Process in one step");
    		jButtonProcessAll.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					SketchContainer.get().segment();
					SketchContainer.get().primApproximate();
					SketchContainer.get().parse();

					repaint();
				}

    		});
    	}
    	return jButtonProcessAll;
    }

    public JButton getJButtonClearSelection() {
    	if (jButtonClearSelection == null) {
    		jButtonClearSelection = new JButton();
    		jButtonClearSelection.setText("Clear selection");
    		jButtonClearSelection.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					SketchContainer.get().clearShapeSelection();
					SketchContainer.get().clearStrokeSelection();
					getJPanelSketch().repaint();
				}

    		});
    	}
    	return jButtonClearSelection;
    }

	public JMenuItem getJMenuViewInk() {
		if (jMenuViewInk == null) {
			jMenuViewInk = new JCheckBoxMenuItem();
			jMenuViewInk.setText("Ink");
			jMenuViewInk.setSelected(false);
			jMenuViewInk.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					showInk();
					getJPanelSketch().repaint();
				}

			});
		}
		return jMenuViewInk;
	}

	public JMenuItem getJMenuViewCxt() {
		if (jMenuViewCxt == null) {
			jMenuViewCxt = new JCheckBoxMenuItem();
			jMenuViewCxt.setText("Context (Shapes)");
			jMenuViewCxt.setSelected(false);
			jMenuViewCxt.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					showCxt();
					getJPanelSketch().repaint();
				}

			});
		}
		return jMenuViewCxt;
	}

	public JMenuItem getJMenuViewHybrid() {
		if (jMenuViewHybrid == null) {
			jMenuViewHybrid = new JCheckBoxMenuItem();
			jMenuViewHybrid.setText("Hybrid (default)");
			jMenuViewHybrid.setSelected(true);
			jMenuViewHybrid.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent arg0) {
					showHybrid();
					getJPanelSketch().repaint();
				}

			});
		}
		return jMenuViewHybrid;
	}

	public JMenuItem getJMenuActionSegment() {
		if (jMenuActionSegment == null) {
			jMenuActionSegment = new JMenuItem();
			jMenuActionSegment.setText("Segment");
			jMenuActionSegment.addActionListener(alSegment);
		}
		return jMenuActionSegment;
	}

	public JMenuItem getJMenuActionPA() {
		if (jMenuActionPA == null) {
			jMenuActionPA = new JMenuItem();
			jMenuActionPA.setText("Prim Approximate");
			jMenuActionPA.addActionListener(alPA);

		}
		return jMenuActionPA;
	}

	public JMenuItem getJMenuActionParse() {
		if (jMenuActionParse == null) {
			jMenuActionParse = new JMenuItem();
			jMenuActionParse.setText("Parse static");
			jMenuActionParse.addActionListener(alParse);

		}
		return jMenuActionParse;
	}

	public JMenuItem getJMenuActionParse2() {
		if (jMenuActionParse2 == null) {
			jMenuActionParse2 = new JMenuItem();
			jMenuActionParse2.setText("Parse dynamic");
			jMenuActionParse2.setAccelerator(KeyStroke.getKeyStroke('p'));
			jMenuActionParse2.addActionListener(alParse2);
		}
		return jMenuActionParse2;
	}

	public JTree getJTreeInk() {
		if (jTreeInk == null) {
			List<Stroke> list = SketchContainer.get().getStrokes();

    		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Strokes (Id:Type:Parent-Id)");
        	jTreeInk = new JTree(root);

        	for (Stroke stroke : list) {
        		DefaultMutableTreeNode node = new DefaultMutableTreeNode(stroke.getId() + ":Stroke:" + stroke.getOriginal());
        		root.add(node);
        	}
        	expandTree(jTreeInk);

        	jTreeInk.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
                public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                    int[] sel = getJTreeSelection(getJTreeInk());
                    if (sel.length == 0) {
                    	return;
                    }
                    SketchContainer.get().setSelectedStrokesByIds(sel);

//                    Stroke stroke = SketchContainer.get().getSelectedStroke();
//                    if (stroke != null) {
//	                    getJTextFieldK1().setText(Integer.toString(stroke.getStaticCD().getK1()));
//	                	getJTextFieldH1().setText(Double.toString(stroke.getStaticCD().getH1()));
//	                	getJTextFieldK2().setText(Integer.toString(stroke.getStaticCD().getK2()));
//	                	getJTextFieldH2().setText(Double.toString(stroke.getStaticCD().getH2()));
//	                	getJTextFieldCorner().setText(Integer.toString(stroke.getCD().getCorners().size()));
//                    }
                    getJPanelSketch().repaint();
                }
            });
		}
		return jTreeInk;
	}

	public JTree getJTreeCxt() {
		if (jTreeCxt == null) {
			List<Shape> list = SketchContainer.get().getShapes();

    		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Shapes (Id:Type)");
        	jTreeCxt = new JTree(root);

        	for (Shape shape : list) {
        		DefaultMutableTreeNode node = new DefaultMutableTreeNode(shape.getId() + ":" +
        				shape.getName());
        		root.add(node);
        	}
        	expandTree(jTreeCxt);

        	jTreeCxt.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
                public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                    int[] sel = getJTreeSelection(getJTreeCxt());
                    if (sel.length == 0) {
                    	return;
                    }
                    SketchContainer.get().setSelectedShapesByIds(sel);
                    resetJTableCxt();
                    getJPanelSketch().repaint();
                }
            });
		}
		return jTreeCxt;
	}

	private int[] getJTreeSelection(JTree tree) {
		TreePath[] paths = tree.getSelectionPaths();
		if (paths == null)
			return new int[0];

		int[] ids = new int[paths.length];

		for (int i = 0; i < paths.length; i++) {
			Object[] path = paths[i].getPath();
    		Object o = path[path.length-1];

    	   	if (o instanceof DefaultMutableTreeNode) {
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) o;
				String value = node.toString();
				String[] vv = value.split(":");
				if (vv.length > 1) {
					try {
						int id = Integer.valueOf(vv[0]);
						ids[i] = id;
					} catch (Exception e) {
	//					TODO:System.out.println(e.getMessage());
					}
				}
			}

    	}
    	return ids;
	}

	private void expandTree(JTree tree) {
		for (int i = 0; i < tree.getRowCount(); i++) {
			tree.expandRow(i);
		}
	}

	private void resetJTreeInk() {
		jTreeInk = null;
		getJScrollPaneInk().setViewportView(getJTreeInk());
	}

	private void resetJTreeCxt() {
		jTreeCxt = null;
		getJScrollPaneCxt().setViewportView(getJTreeCxt());
	}

	private void resetJTableCxt() {
		jTableCxt = null;
		getJScrollPaneCxtTable().setViewportView(getJTableCxt());
	}

//	private void resetJTreeConcept() {
//		jTreeConcept = null;
//		getJScrollPaneConcept().setViewportView(getJTreeConcept());
//	}
//
//	private void resetJTreeRelation() {
//		jTreeRelation = null;
//		getJScrollPaneRelation().setViewportView(getJTreeRelation());
//	}
//
//	private void resetJTableSemantics() {
//		jTableSemantics = null;
//		getJScrollPaneSemanticsTable().setViewportView(getJTableSemantics());
//	}

	private void showInk() {
//		getJTabbedPane().setSelectedIndex(0);
		getJMenuViewInk().setSelected(true);
		getJMenuViewCxt().setSelected(false);
		getJMenuViewHybrid().setSelected(false);
	}

	private void showCxt() {
//		getJTabbedPane().setSelectedIndex(1);
		getJMenuViewInk().setSelected(false);
		getJMenuViewHybrid().setSelected(false);
		getJMenuViewCxt().setSelected(true);
	}

	private void showHybrid() {
		getJMenuViewHybrid().setSelected(true);
		getJMenuViewInk().setSelected(false);
		getJMenuViewCxt().setSelected(false);
	}

	public void repaint() {
		super.repaint();

		SketchContainer.get().clearStrokeSelection();
		SketchContainer.get().clearShapeSelection();
		resetJTreeInk();
		resetJTreeCxt();
		resetJTableCxt();
		getJPanelSketch().repaint();
	}

	public javax.swing.JCheckBox getJCheckBoxAutoSeg() {
		if (jCheckBoxAutoSeg == null) {
			jCheckBoxAutoSeg = new JCheckBox();
			jCheckBoxAutoSeg.setText("Auto segmentation");
	        jCheckBoxAutoSeg.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
	        jCheckBoxAutoSeg.setMargin(new java.awt.Insets(0, 0, 0, 0));

		}
		return jCheckBoxAutoSeg;
	}

	public javax.swing.JComboBox getJComboBoxCDMethod() {
		if (jComboBoxCDMethod == null) {
			jComboBoxCDMethod = new JComboBox();

			jComboBoxCDMethod.setModel(new DefaultComboBoxModel(
					CDFactory.getTypes()
			));

			jComboBoxCDMethod.setSelectedItem(SketchContainer.get().getCD().getType());
//			jComboBoxCDMethod.setSelectedItem(CDFactory.TYPE.DynamicKH);
			jComboBoxCDMethod.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					SketchContainer.get().setCD(
							CDFactory.getCD(
							getJComboBoxCDMethod().getSelectedItem().toString()));

					getJPanelSketch().repaint();
				}

			});
		}
		return jComboBoxCDMethod;
	}

	public javax.swing.JLabel getJLabelCDMethod() {
		if (jLabelCDMethod == null) {
			jLabelCDMethod = new JLabel();
			jLabelCDMethod.setText("Corner detection method:");
		}
		return jLabelCDMethod;
	}

	public javax.swing.JLabel getJLabelCorner() {
		if (jLabelCorner == null) {
			jLabelCorner = new JLabel();
			jLabelCorner.setText("Number of corners:");
		}
		return jLabelCorner;
	}

	public javax.swing.JTextField getJTextFieldCorner() {
		if (jTextFieldCorner == null) {
			jTextFieldCorner = new JTextField();
			jTextFieldCorner.setEditable(false);
		}
		return jTextFieldCorner;
	}

	public javax.swing.JButton getJButtonPA() {
		if (jButtonPA == null) {
			jButtonPA = new JButton();
			jButtonPA.setText("PA");
			jButtonPA.addActionListener(alPA);
		}
		return jButtonPA;
	}

	public javax.swing.JButton getJButtonSeg() {
		if (jButtonSeg == null) {
			jButtonSeg = new JButton();
			jButtonSeg.setText("Seg");
			jButtonSeg.addActionListener(alSegment);
		}
		return jButtonSeg;
	}

	public javax.swing.JCheckBox getJCheckBoxAutoPA() {
		if (jCheckBoxAutoPA == null) {
			jCheckBoxAutoPA = new JCheckBox();
			jCheckBoxAutoPA.setText("Auto primitive approximation");
	        jCheckBoxAutoPA.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
	        jCheckBoxAutoPA.setMargin(new java.awt.Insets(0, 0, 0, 0));
		}
		return jCheckBoxAutoPA;
	}

	private ActionListener alSegment = new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			SketchContainer.get().segment();
			repaint();
		}

	};

	private ActionListener alPA = new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			SketchContainer.get().primApproximate();
			repaint();
		}

	};

	private ActionListener alParse = new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			SketchContainer.get().parse();
			repaint();
		}

	};

	private ActionListener alParse2 = new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			SketchContainer.get().parse2();
			repaint();
		}

	};

	public JButton getJButtonParse() {
		if (jButtonParse == null) {
			jButtonParse = new JButton();
			jButtonParse.setText("Parse static shapes");
			jButtonParse.addActionListener(alParse);
		}
		return jButtonParse;
	}

	public JButton getJButtonParse2() {
		if (jButtonParse2 == null) {
			jButtonParse2 = new JButton();
			jButtonParse2.setText("Parse dynamic shapes");
			jButtonParse2.addActionListener(alParse2);
		}
		return jButtonParse2;
	}

	public JCheckBox getJCheckBoxAutoParse() {
		if (jCheckBoxAutoParse == null) {
			jCheckBoxAutoParse = new JCheckBox();
			jCheckBoxAutoParse.setText("Set to auto");
	        jCheckBoxAutoParse.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
	        jCheckBoxAutoParse.setMargin(new java.awt.Insets(0, 0, 0, 0));

		}
		return jCheckBoxAutoParse;
	}

	private JLabel jLabelDomain;
	private JComboBox jComboBoxDomain;

	public JLabel getJLabelDomain() {
		if (jLabelDomain == null) {
			jLabelDomain = new JLabel();
			jLabelDomain.setText("Parsing domain:");
		}
		return jLabelDomain;
	}

	public JComboBox getJComboBoxDomain() {
		if (jComboBoxDomain == null) {
			jComboBoxDomain = new JComboBox();
			jComboBoxDomain.setModel(new DefaultComboBoxModel(Parser.getDomains()));
			jComboBoxDomain.setSelectedItem(Parser.get().getDomain());
			jComboBoxDomain.addActionListener(new ActionListener() {

				public void actionPerformed(ActionEvent e) {
					Parser.get().setDomain((Parser.DOMAIN)jComboBoxDomain.getSelectedItem());
					if (getJCheckBoxAutoParse().isSelected()) {
						SketchContainer.get().parse();
						repaint();
					}
				}

			});
//			jComboBoxDomain.addActionListener(alParse);
		}
		return jComboBoxDomain;
	}

//	private JPanel jPanelSemantics;
//	private JScrollPane jScrollPaneConcept;
//	private JScrollPane jScrollPaneRelation;
//	private JScrollPane jScrollPaneSemanticsTable;
//	private JTable jTableSemantics;
//	private JButton jButtonGenerate;
//
//	public JPanel getJPanelSemantics() {
//		if (jPanelSemantics == null) {
//			jPanelSemantics = new JPanel();
//
//			org.jdesktop.layout.GroupLayout jPanelSemanticsLayout = new org.jdesktop.layout.GroupLayout(jPanelSemantics);
//	        jPanelSemantics.setLayout(jPanelSemanticsLayout);
//	        jPanelSemanticsLayout.setHorizontalGroup(
//	            jPanelSemanticsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
//	            .add(getJScrollPaneConcept(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
//	            .add(getJScrollPaneRelation(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
//	            .add(getJScrollPaneSemanticsTable(), org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
//	            .add(jPanelSemanticsLayout.createSequentialGroup()
//	                .add(getJButtonGenerate())
//	                .addContainerGap())
//	        );
//	        jPanelSemanticsLayout.setVerticalGroup(
//	            jPanelSemanticsLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
//	            .add(jPanelSemanticsLayout.createSequentialGroup()
//	                .add(getJScrollPaneConcept(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 179, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
//	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
//	                .add(getJScrollPaneRelation(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 198, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
//	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
//	                .add(getJScrollPaneSemanticsTable(), org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 92, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
//	                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
//	                .add(getJButtonGenerate())
//	                .addContainerGap(49, Short.MAX_VALUE))
//	        );
//		}
//		return jPanelSemantics;
//	}
//
//	public JScrollPane getJScrollPaneConcept() {
//		if (jScrollPaneConcept == null) {
//			jScrollPaneConcept = new JScrollPane();
//		}
//		return jScrollPaneConcept;
//	}
//
//	public JScrollPane getJScrollPaneRelation() {
//		if (jScrollPaneRelation == null) {
//			jScrollPaneRelation = new JScrollPane();
//
//		}
//		return jScrollPaneRelation;
//	}
//
//	public JScrollPane getJScrollPaneSemanticsTable() {
//		if (jScrollPaneSemanticsTable == null) {
//			jScrollPaneSemanticsTable = new JScrollPane();
//			jScrollPaneSemanticsTable.setViewportView(getJTableSemantics());
//		}
//		return jScrollPaneSemanticsTable;
//	}
//
//	public JTable getJTableSemantics() {
//		if (jTableSemantics == null) {
//			jTableSemantics = new JTable();
//
//		}
//		return jTableSemantics;
//	}
//
//	public JButton getJButtonGenerate() {
//		if (jButtonGenerate == null) {
//			jButtonGenerate = new JButton();
//			jButtonGenerate.setText("Generate Semantics");
//		}
//		return jButtonGenerate;
//	}
//
//	private JTree jTreeConcept;
//	private JTree jTreeRelation;
//
//	public JTree getJTreeConcept() {
//		if (jTreeConcept == null) {
//			jTreeConcept = new JTree();
//		}
//		return jTreeConcept;
//	}
//
//	public JTree getJTreeRelation() {
//		if (jTreeRelation == null) {
//			jTreeConcept = new JTree();
//		}
//		return jTreeConcept;
//	}
}
